package csl.blog.server.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import csl.blog.server.config.redis.IDistributedLocker;
import csl.blog.server.mq.produce.EventProducer;
import csl.blog.server.mq.produce.MsgEvent;
import csl.blog.server.netty.handler.ClientUserHandler;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @Description: TODO
 * @author: 隔山海
 * @date: 2021年10月09日 10:20
 */
@Slf4j
@RestController
@RequestMapping("test")
public class TestController {

    @Autowired
    private EventProducer eventProducer;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ClientUserHandler clientUserHandler;

    @Autowired
    private IDistributedLocker distributedLocker;

    @RequestMapping(value = "/sendRedis", method = RequestMethod.GET)
    public void sendRedis() {
        String key = UUID.randomUUID().toString();
        String data = "12";
        redisTemplate.opsForValue().set(key, data);
        log.info("写入缓存成功！====>{}", data);
        String s1 = redisTemplate.opsForValue().get(key);
        Boolean isDelete = redisTemplate.delete(key);
        log.info("清除数据====>{},处理结果===>{}", s1, isDelete);
    }

    @RequestMapping(value = "sendMQ", method = RequestMethod.GET)
    public void sendMQ() {
        MsgEvent event = new MsgEvent();
        event.setTaskId(UUID.randomUUID().toString());
        event.setTaskTag("sendMQ");
        event.setName("csl");
        event.setData(DateUtil.now());
        eventProducer.send(event);
    }

    @GetMapping("/token")
    public String getToken() {
        String token = IdUtil.fastSimpleUUID();
        ClientUserHandler.userMap.put(token, token);
        return token;
    }

    @PostMapping("/tips")
    public void sendToClient(@RequestParam("tips") String tips, @RequestParam("userId") String userId) {
        Map<String, Channel> channelMap = clientUserHandler.channelMap;
        Channel channel = channelMap.get(userId);
        if (ObjectUtil.isNotNull(channel)) {
            channel.writeAndFlush(tips);
        }
    }

    @GetMapping("lock")
    public Integer lock() throws Exception {
        AtomicInteger integer = new AtomicInteger(0);
        distributedLocker.lock(Thread.currentThread().getName(), () -> {
            integer.getAndIncrement();
            return null;
        });
        ExecutorService service = Executors.newFixedThreadPool(10);
        List<Runnable> tasks = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            tasks.add(integer::getAndIncrement);
        }
        CompletableFuture.allOf(tasks.stream()
                .map(task -> CompletableFuture.runAsync(task, service))
                .toArray(CompletableFuture[]::new)).join();
        return integer.get();
    }
}
